/**
 * Copyright (C) 2018-2019
 * All rights reserved, Designed By www.joolun.com
 */
package com.joolun.web.controller.weixin;

import com.alibaba.fastjson2.JSON;
import com.joolun.common.annotation.Anonymous;
import com.joolun.common.core.domain.AjaxResult;
import com.joolun.common.core.redis.RedisCache;
import com.joolun.common.utils.StringUtils;
import com.joolun.common.utils.uuid.IdUtils;
import com.joolun.weixin.entity.LoginMaDTO;
import com.joolun.weixin.entity.WxOpenDataDTO;
import com.joolun.weixin.entity.WxUser;
import com.joolun.weixin.entity.vo.WxLoginVo;
import com.joolun.weixin.service.WxUserService;
import com.joolun.weixin.utils.ThirdSessionHolder;
import com.joolun.weixin.utils.WxMaUtil;
import jakarta.servlet.http.HttpServletRequest;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket;
import org.apache.ibatis.annotations.Param;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 微信用户
 *
 * @author www.joolun.com
 * @date 2019-08-25 15:39:39
 */
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("/weixin/api/ma/wxuser")
public class WxUserApi {

	private final WxUserService wxUserService;
    private final WxMpService wxService;


    @Autowired
    private RedisCache redisCache;


    /**
	 * 小程序用户登录
	 * @param request
	 * @param loginMaDTO
	 * @return
	 */
	@PostMapping("/login")
	public AjaxResult login(HttpServletRequest request, @RequestBody LoginMaDTO loginMaDTO){
		try {
			WxUser wxUser = wxUserService.loginMa(WxMaUtil.getAppId(request),loginMaDTO.getJsCode());
			return AjaxResult.success(wxUser);
		} catch (Exception e) {
			e.printStackTrace();
			return AjaxResult.error(e.getMessage());
		}
	}

	/**
	 * 获取用户信息
	 * @param
	 * @return
	 */
	@GetMapping
	public AjaxResult get(){
		String id = ThirdSessionHolder.getThirdSession().getWxUserId();
		return AjaxResult.success(wxUserService.getById(id));
	}

	/**
	 * 保存用户信息
	 * @param wxOpenDataDTO
	 * @return
	 */
	@PostMapping
	public AjaxResult saveOrUptateWxUser(@RequestBody WxOpenDataDTO wxOpenDataDTO){
		wxOpenDataDTO.setAppId(ThirdSessionHolder.getThirdSession().getAppId());
		wxOpenDataDTO.setUserId(ThirdSessionHolder.getThirdSession().getWxUserId());
		wxOpenDataDTO.setSessionKey(ThirdSessionHolder.getThirdSession().getSessionKey());
		WxUser wxUser = wxUserService.saveOrUptateWxUser(wxOpenDataDTO);
		return AjaxResult.success(wxUser);
	}


    /**
     * 生成二维码接口
     * @return
     */
    @GetMapping("/qrcode")
    @Anonymous
    public AjaxResult<Map<String, String>> generateQrCode() {
        // 生成唯一 scene_id
        String sceneId = IdUtils.randomUUID().toString();

        WxMpQrCodeTicket wxMpQrCodeTicket;
        // 调用微信生成二维码接口
        try {
             wxMpQrCodeTicket =  wxService.getQrcodeService().qrCodeCreateTmpTicket(sceneId,300);
            log.info("--创建临时二维码ticket返回：{}", JSON.toJSONString(wxMpQrCodeTicket));
        } catch (WxErrorException e) {
            throw new RuntimeException(e);
        }
        // 解析响应，获取二维码 URL
        String ticket = wxMpQrCodeTicket.getTicket();
        String qrcodeUrl = wxMpQrCodeTicket.getUrl();
        // 存储 scene_id 状态（标记为待扫描）
        redisCache.setCacheObject("scene:" + sceneId,"pending");
        // 返回结果
        return AjaxResult.success(qrcodeUrl,sceneId);
    }


    /**
     * 检测是否扫码
     * @param sceneId
     * @return
     */
    @GetMapping("/api/check-login")
    public AjaxResult<Map<String, Object>> checkLoginStatus(@RequestParam("scene_id") String sceneId) throws IOException {

        // 1. 参数校验
        if (sceneId == null || sceneId.isEmpty()) {
            return AjaxResult.error("scene_id 不能为空");
        }

        // 2. 从 Redis 中查询状态
        String statusKey = "scene:" + sceneId;
        String status = redisCache.getCacheObject(statusKey);

        // 3. 处理状态不存在或已过期
        if (StringUtils.isEmpty(status)) {
            return AjaxResult.error(102,"二维码已过期，请刷新重试");
        }

        // 4. 根据状态返回不同结果
        Map<String, Object> response = new HashMap<>();
        switch (status) {
            case "pending":
                response.put("status", "pending");
                response.put("message", "等待扫码");
                break;
            case "scanned":
                response.put("status", "scanned");
                response.put("message", "已扫码，等待授权");
                break;
            case "authorized":
                // 获取用户信息
                String userInfoKey = "user:" + sceneId;
                String userInfoJson = redisCache.getCacheObject(userInfoKey);
                if (userInfoJson != null) {
                    // 解析用户信息（示例使用 JSON，实际可替换为具体对象）
                    Map<String, Object> userInfo = parseUserInfo(userInfoJson);
                    response.put("status", "authorized");
                    response.put("user_info", userInfo);
                    // 清理 Redis 数据（避免重复使用）
                    redisCache.deleteObject(statusKey);
                    redisCache.deleteObject(userInfoKey);
                } else {
                    response.put("status", "error");
                    response.put("message", "用户信息获取失败");
                }
                break;
            default:
                response.put("status", "error");
                response.put("message", "未知状态");
        }

        return AjaxResult.success(response);
    }

    // 解析用户信息（示例）
    private Map<String, Object> parseUserInfo(String userInfoJson) throws IOException {
        return new ObjectMapper().readValue(userInfoJson, Map.class);
    }

    /**
     * 检测用户是否在手机端授权
     * @param uuid
     * @return
     */
    @GetMapping("uuid")
    public AjaxResult<WxLoginVo> checkLogin(String uuid) throws IOException {
        WxLoginVo wxLoginVo = new WxLoginVo();
        System.out.println("uuid:" + uuid);
        // 1. 参数校验
        if (uuid == null || uuid.isEmpty()) {
            return AjaxResult.success("用户未授权");
        }
        // 2. 从 Redis 中查询授权的用户
        WxUser wxUser = redisCache.getCacheObject(uuid);
        if (wxUser != null) {
            System.out.println("wxUser:" + wxUser);
            wxLoginVo.setWxUser(wxUser);
            // 清理 Redis 数据（避免重复使用）
            redisCache.deleteObject(uuid);
        } else {
            Boolean isEwm = redisCache.getCacheObject(uuid + "uuid");
            System.out.println("isEwm-----------------------------" + isEwm);
            if(isEwm == null){
                redisCache.setCacheObject(uuid + "uuid", true,1, TimeUnit.MINUTES);
            }
            return AjaxResult.success("用户未授权");
        }
        return AjaxResult.success(wxLoginVo);
    }
    /**
     * 二维码已过期
     * @param uuid
     * @return
     */
    @GetMapping("outUuid")
    public void checkOutLogin(String uuid) throws IOException {
        System.out.println("--------------uuid:" + uuid);
        // 设置二维码已过期标识
        if (uuid == null || uuid.isEmpty()) {
            redisCache.setCacheObject(uuid + "uuid", false,1, TimeUnit.MINUTES);
        }
    }

}
